package com.google.gdata.data.douban;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.xml.sax.Attributes;

import com.google.gdata.client.CoreErrorDomain;
import com.google.gdata.data.AttributeGenerator;
import com.google.gdata.data.AttributeHelper;
import com.google.gdata.data.BaseEntry;
import com.google.gdata.data.ExtensionDescription;
import com.google.gdata.data.ExtensionPoint;
import com.google.gdata.data.ExtensionProfile;
import com.google.gdata.data.Link;
import com.google.gdata.data.Person;
import com.google.gdata.data.TextConstruct;
import com.google.gdata.data.extensions.Rating;
import com.google.gdata.util.ParseException;
import com.google.gdata.util.XmlParser;
import com.google.gdata.util.XmlParser.ElementHandler;
import com.google.gdata.util.common.xml.XmlWriter;

/**
 * User entry specific for a douban user. Contains setters and getters for all
 * fields specific to user data.
 */

@ExtensionDescription.Default(nsAlias = Namespaces.doubanAlias, nsUri = Namespaces.doubanNamespace, localName = "entity", isRepeatable = true)
public class Entity extends BaseEntry<Entity> {

	public Entity() {
		super();
	}

	public Entity(BaseEntry sourceEntry) {
		super(sourceEntry);
	}

	protected TextConstruct uri;
	protected TextConstruct name;

	
	public TextConstruct getUri() {
		return uri;
	}

	public void setUri(TextConstruct uri) {
		this.uri = uri;
	}

	public TextConstruct getName() {
		return name;
	}

	public void setName(TextConstruct name) {
		this.name = name;
	}

	protected String entityName;

	public String getEntityName() {
		return entityName;
	}

	public void setEntityName(String v) {
		entityName = v;
	}

	protected String entityIndex;

	public String getEntityIndex() {
		return entityIndex;
	}

	public void setEntityIndex(String v) {
		entityIndex = v;
	}

	protected String entityLang;

	public String getEntityLang() {
		return entityLang;
	}

	public void setEntityLang(String v) {
		entityLang = v;
	}

	public static ExtensionDescription getDefaultDescription(boolean repeatable) {
		ExtensionDescription desc = ExtensionDescription
				.getDefaultDescription(Entity.class);
		desc.setRepeatable(repeatable);
		return desc;
	}

	@Override
	public void declareExtensions(ExtensionProfile extProfile) {

		super.declareExtensions(extProfile);

		extProfile.declareArbitraryXmlExtension(Entity.class);
	}

	@Override
	public Handler getHandler(ExtensionProfile extProfile, String namespace,
			String localName, Attributes attrs) {
		return new Handler(extProfile);
	}

	private class Handler extends AtomHandler {

		public Handler(ExtensionProfile arg0) {
			super(arg0);
			// TODO Auto-generated constructor stub
		}

		public void processAttribute(String namespace, String localName,
				String value) throws ParseException {
			if (localName.equals("name")) {
				setEntityName(value);
			}
		}

		@Override
		public XmlParser.ElementHandler getChildHandler(String namespace,
				String localName, Attributes attrs) throws ParseException,
				IOException {
			if (localName.equals("name")) {
				TextConstruct.ChildHandlerInfo chi = TextConstruct
						.getChildHandler(attrs);

				if (name != null) {
					throw new ParseException("");
				}
				name = chi.textConstruct;
				return chi.handler;
			} else if (localName.equals("uri")) {
				TextConstruct.ChildHandlerInfo chi = TextConstruct
						.getChildHandler(attrs);

				if (uri != null) {
					throw new ParseException("");
				}
				uri = chi.textConstruct;
				return chi.handler;
			} else {
				return super.getChildHandler(namespace, localName, attrs);
			}
		}

	}
	
	public void generate(XmlWriter w, ExtensionProfile extProfile)
	throws IOException {
		List<XmlWriter.Attribute> additionalAttrs = new ArrayList<XmlWriter.Attribute>();
		XmlWriter.Attribute a = new XmlWriter.Attribute("name", this.getEntityName());
		additionalAttrs.add(a);
		
		if(this.getEntityIndex()!=null){
			XmlWriter.Attribute a1 = new XmlWriter.Attribute("index", this.getEntityIndex());
			additionalAttrs.add(a1); 
		}
		
		if(this.getEntityIndex()!=null){
			XmlWriter.Attribute a2 = new XmlWriter.Attribute("lang", this.getEntityLang());
			additionalAttrs.add(a2);
		}
		
		generateStartElement(w, Namespaces.doubanNs, "entity", additionalAttrs, null); 
	    if (uri != null) {
	    	  w.simpleElement(null, "uri", null, this.getUri().getPlainText() );
	    }

	    // Invoke ExtensionPoint.
	    generateExtensions(w, extProfile);

	    w.endElement(Namespaces.doubanNs, "entity");
	}

}